package com.whz.iplocation.http;

import com.whz.iplocation.thread.ThreadPoolUtils;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import java.util.concurrent.TimeUnit;

/**
 * @author whz
 */
@Slf4j
@UtilityClass
public class HttpClientFactoryUtils {

    public HttpClientConnectionManager buildPoolManager(final HttpClientPoolConfig httpClientPoolConfig) {
        PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(
                httpClientPoolConfig.getTimeToLive(),
                httpClientPoolConfig.getTimeUnitToLive()
        );
        manager.setMaxTotal(httpClientPoolConfig.getMaxTotalConnections());
        manager.setDefaultMaxPerRoute(httpClientPoolConfig.getMaxConnectionsPerRoute());
        cleanPoolFixRate(manager, httpClientPoolConfig);
        return manager;
    }

    private void cleanPoolFixRate(final HttpClientConnectionManager manager, final HttpClientPoolConfig httpClientPoolConfig) {
        // 启动定时器，定时回收过期的连接
        ThreadPoolUtils.asyncScheduledExecutorService("thread-pool-clear").scheduleAtFixedRate(() -> {
                    manager.closeExpiredConnections();
                    manager.closeIdleConnections(
                            httpClientPoolConfig.getTimeToLive(),
                            httpClientPoolConfig.getTimeUnitToLive()
                    );
                },
                30,
                30,
                TimeUnit.SECONDS);
    }

    public static CloseableHttpClient creatDefaultHttpClient() {
        return creatHttpClient(new HttpClientPoolConfig());
    }

    public static CloseableHttpClient creatHttpClient(final HttpClientPoolConfig httpClientPoolConfig) {
        return creatHttpClient(httpClientPoolConfig, httpClientPoolConfig.getDefaultRequestConfig());
    }

    public static CloseableHttpClient creatHttpClient(final HttpClientPoolConfig httpClientPoolConfig, final RequestConfig requestConfig) {
        log.info("http client pool config:{}", httpClientPoolConfig);
        log.info("http client request config:{}", requestConfig);

        return HttpClientBuilder.create()
                .disableCookieManagement()
                .useSystemProperties()
                .setConnectionManager(buildPoolManager(httpClientPoolConfig))
                .setDefaultRequestConfig(requestConfig)
                .build();
    }
}